﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Happy.ExtentionMethods;

namespace Happy.ExceptionHanding
{
    /// <summary>
    /// 异常信息提供者注册处。
    /// </summary>
    public static class ExceptionInformationProviderRegistry
    {
        private static readonly Dictionary<Type, IExceptionInformationProvider> _providers
            = new Dictionary<Type, IExceptionInformationProvider>();

        /// <summary>
        /// 注册提供者。
        /// </summary>
        public static void Register<TException>(IExceptionInformationProvider provider)
            where TException : Exception
        {
            Register(typeof(TException), provider);
        }

        /// <summary>
        /// 注册提供者。
        /// </summary>
        public static void Register(Type exceptionType, IExceptionInformationProvider provider)
        {
            exceptionType.MustNotNull("exceptionType");
            provider.MustNotNull("provider");

            _providers[exceptionType] = provider;
        }

        public static Dictionary<string, object> CreateInformation(Exception exception)
        {
            exception.MustNotNull("exception");

            var exceptionType = exception.GetType();

            var information = CreateDefaultInformation(exception);

            if (_providers.ContainsKey(exceptionType))
            {
                var extInformation = _providers[exceptionType].CreateInformation(exception);

                foreach (var item in extInformation.ToDictionary())
                {
                    information[item.Key] = item.Value;
                }
            }
            else
            {
                if (FriendlyExceptionRegistry.IsFriendly(exception.GetType()))
                {
                    information["exception"] = Resource.Messages.Msg_DefaultExceptionMessage;
                }
            }

            return information;
        }

        private static Dictionary<string, object> CreateDefaultInformation(Exception exception)
        {
            return new Dictionary<string, object> 
            { 
                { "success", false },
                { "exception", exception.GetType().Name },
                { "message",exception.Message }
            };
        }
    }
}
